package com.liruo.srpingframework.dataaccess.transaction.selfinvocation;

import com.liruo.srpingframework.dataaccess.transaction.TransactionEntity;
import com.liruo.srpingframework.dataaccess.transaction.TransactionEntityRepository;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
public class TransactionSelfInvocationService {
  @Resource
  TransactionEntityRepository repository;

  public void noTransactionMethodLegalCallTransactionMethod() {
    TransactionSelfInvocationService service = (TransactionSelfInvocationService) AopContext.currentProxy();
    service.transactionMethod1(true, "noTransactionMethodNoThrowHere");
  }
  public void noTransactionMethodNoThrowHere() {
    transactionMethod1(true, "noTransactionMethodNoThrowHere");
  }
  public void noTransactionMethodThrowHere() {
    transactionMethod1(false, "noTransactionMethodThrowHere");
    throw new RuntimeException("transactionMethod1");
  }
  @Transactional
  public void transactionMethod1(boolean error, String where) {
    repository.save(new TransactionEntity(null,  where + " call transactionMethod1"));
    if(error){
      throw new RuntimeException("transactionMethod1");
    }
  }

  @Transactional
  public void transactionMethodNoThrowHere() {
    noTransactionMethod2(true, "transactionMethodNoThrowHere");
  }
  @Transactional
  public void transactionMethodThrowHere() {
    noTransactionMethod2(false, "transactionMethodThrowHere");
    throw new RuntimeException("transactionMethod1");
  }
  public void noTransactionMethod2(boolean error, String where) {
    repository.save(new TransactionEntity(null, where + " call transactionMethod1"));
    if(error){
      throw new RuntimeException("transactionMethod1");
    }
  }
}
